/* Copyright 2011 Brian Cairns
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.wsnetwork.reforger.rogue;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import net.wsnetwork.reforger.SpecModel;
import net.wsnetwork.reforger.Stat;

public class CombatSpecModel implements SpecModel {

    private float YELLOW_HIT_COEFFICIENT = 3.4f;
    private float WHITE_HIT_COEFFICIENT = 1.3f;
    private float EXP_COEFFICIENT = 2.3f;
    private float MST_COEFFICIENT = 1.7f;
    private float HST_COEFFICIENT = 1.9f;
    private float CRI_COEFFICIENT = 1.3f;

    // EP value of yellow hit at the hit cap
    private float EP_AT_YELLOW_CAP = YELLOW_HIT_COEFFICIENT * YELLOW_HIT_CAP;

    // EP value of expertise at the hit cap
    private float EP_AT_EXP_CAP = EXP_CAP * EXP_COEFFICIENT;
       
    private float BEST_COEFFICIENT;
    
    public CombatSpecModel(HashMap<String,Double> ep){
    	YELLOW_HIT_COEFFICIENT = ep.get("style_hit").floatValue();
    	WHITE_HIT_COEFFICIENT = ep.get("white_hit").floatValue();
    	EXP_COEFFICIENT = ep.get("exp").floatValue();
    	MST_COEFFICIENT = ep.get("mastery").floatValue();
    	HST_COEFFICIENT = ep.get("haste").floatValue();
    	CRI_COEFFICIENT = ep.get("crit").floatValue();
    	
    	// reset the cap eps
    	EP_AT_YELLOW_CAP = YELLOW_HIT_COEFFICIENT * YELLOW_HIT_CAP;
        EP_AT_EXP_CAP = EXP_CAP * EXP_COEFFICIENT;
        
        // calc best stat except exp and yellow hit
        BEST_COEFFICIENT = WHITE_HIT_COEFFICIENT;
        if(MST_COEFFICIENT > BEST_COEFFICIENT)
        	BEST_COEFFICIENT = MST_COEFFICIENT;
        if(HST_COEFFICIENT > BEST_COEFFICIENT)
        	BEST_COEFFICIENT = HST_COEFFICIENT;
        if(CRI_COEFFICIENT > BEST_COEFFICIENT)
        	BEST_COEFFICIENT = CRI_COEFFICIENT;
        if(EXP_COEFFICIENT > BEST_COEFFICIENT)
        	BEST_COEFFICIENT = EXP_COEFFICIENT;
    }

    public CombatSpecModel() {
	}

	@Override public float calculateEp(int[] statValues) {
        float result = 0;

        int hit = statValues[Stat.hit.getIndex()];
        if (hit > YELLOW_HIT_CAP) {
            result += (hit - YELLOW_HIT_CAP) * WHITE_HIT_COEFFICIENT;
            result += EP_AT_YELLOW_CAP;
        } else {
            result += hit * YELLOW_HIT_COEFFICIENT;
        }

        int exp = statValues[Stat.exp.getIndex()];
        if (exp > EXP_CAP) {
            result += EP_AT_EXP_CAP;
        } else {
            result += exp * EXP_COEFFICIENT;
        }

        result += statValues[Stat.mst.getIndex()] * MST_COEFFICIENT;
        result += statValues[Stat.hst.getIndex()] * HST_COEFFICIENT;
        result += statValues[Stat.cri.getIndex()] * CRI_COEFFICIENT;
        return result;
    }

    @Override public Map<Stat, Set<Stat>> getPossibleReforgings() {
        HashMap<Stat, Set<Stat>> result = new HashMap<Stat, Set<Stat>>();
        Set<Stat> stats = new HashSet<Stat>();
        stats.add(Stat.exp);
        stats.add(Stat.hst);
        stats.add(Stat.mst);
        result.put(Stat.hit, stats);

        stats = new HashSet<Stat>();
        stats.add(Stat.hit);
        stats.add(Stat.exp);
        stats.add(Stat.hst);
        result.put(Stat.mst, stats);

        stats = new HashSet<Stat>();
        stats.add(Stat.exp);
        stats.add(Stat.hit);
        result.put(Stat.hst, stats);

        stats = new HashSet<Stat>();
        stats.add(Stat.hit);
        stats.add(Stat.hst);
        stats.add(Stat.mst);
        result.put(Stat.exp, stats);

        stats = new HashSet<Stat>();
        stats.add(Stat.exp);
        stats.add(Stat.hit);
        stats.add(Stat.mst);
        stats.add(Stat.hst);
        result.put(Stat.cri, stats);

        return result;
    }

    @Override
    public float calculateEpMaxDelta(Stat from, int amount) {
        switch (from) {
        case cri:
            return (YELLOW_HIT_COEFFICIENT - CRI_COEFFICIENT) * amount;
        case hst:
            return (YELLOW_HIT_COEFFICIENT - HST_COEFFICIENT) * amount;
        case mst:
            return (YELLOW_HIT_COEFFICIENT - MST_COEFFICIENT) * amount;
        case hit:
            return (BEST_COEFFICIENT - WHITE_HIT_COEFFICIENT) * amount;
        case exp:
            return (YELLOW_HIT_COEFFICIENT - EXP_COEFFICIENT) * amount;
        }
        return 0;
    }
    
}
